<?php

namespace Xrfg\Api\Trading\Account\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Throwable;
use Xrfg\Core\Trading\Account\Models\Coin;
use Xrfg\Core\Trading\Account\Models\Withdraw;
use Xrfg\Api\Trading\Account\Requests\WithdrawRequest;
use Xrfg\Api\Trading\Account\Resources\ExportResource;
use Xrfg\Core\Trading\Account\Models\Account;
use Xrfg\Core\User\Models\User;
use Xrfg\Core\User\Models\UserSecuritySettingsLog;

class WithdrawController extends Controller
{
    /**
     * 提现记录.
     *
     * @param Coin    $coin
     * @param Request $request
     *
     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
     */
    public function index(Coin $coin, Request $request)
    {
        $perPage = $request->query('per_page', 15);
        $perPage = $perPage > 100 ? 100 : $perPage;

        $withdraws = Withdraw::where('user_id', Auth::id())
            ->when($coin->exists, function (Builder $query) use ($coin) {
                return $query->where('coin_id', $coin->id);
            })
            ->orderByDesc('id')
            ->paginate($perPage);

        return ExportResource::collection($withdraws);
    }

    /**
     * 申请提现.
     *
     * @param WithdrawRequest $request
     *
     * @return \Illuminate\Http\Response
     *
     * @throws \Exception
     */
    public function store(WithdrawRequest $request)
    {
        $coinId = $request->input('coin_id');
        $number = $request->input('number');
        $chainName = $request->input('chain_name');

        /** @var User $user */
        $user = Auth::user();

        // 修改安全设置后，24小时不能提现
        $userSecuritySettingsLog = UserSecuritySettingsLog::where('user_id', $user->id)
            ->where('created_at', '>=', now()->subDay())
            ->first();
        if (!app()->isLocal() && $userSecuritySettingsLog) {
            $this->error(20009);
        }

        $coin = Coin::where('id', $coinId)->first();
        if (1 !== $coin->can_withdraw) {
            $this->error(20003);
        }
        // 数量限制
        if ('USDT' == $coin->name && 'ERC20' == $chainName) {
            $coin->withdraw_max = config('usdt.erc20.withdraw.max');
            $coin->withdraw_min = config('usdt.erc20.withdraw.min');
        }
        if ('USDT' == $coin->name && 'TRC20' == $chainName) {
            $coin->withdraw_max = config('usdt.trc20.withdraw.max');
            $coin->withdraw_min = config('usdt.trc20.withdraw.min');
        }
        if ($number > $coin->withdraw_max) {
            $this->error(20004);
        }
        if ($number < $coin->withdraw_min) {
            $this->error(20005);
        }
        // 检查交易密码设置
        if (!$user->pay_password) {
            $this->error(20006);
        }
        // 检查实名认证状态
        if (1 !== $user->kyc_status) {
            $this->error(20007);
        }

        // 获取提现账户
        $account = Account::firstOrCreate([
            'user_id' => $user->id,
            'coin_id' => $coinId,
        ]);

        // 检查账户余额
        if (!isset($account->available) || $account->available < $number) {
            $this->error(20002);
        }

        // 提现
        if ('USDT' == $coin->name && 'ERC20' == $chainName) {
            $fee = config('usdt.erc20.withdraw.fee');
        } else if ('USDT' == $coin->name && 'TRC20' == $chainName) {
            $fee = config('usdt.trc20.withdraw.fee');
        } else {
            $fee = $coin->withdraw_fee;
        }


        $withdraw = new Withdraw();
        $withdraw->user_id = $user->id;
        $withdraw->coin_id = $coinId;
        $withdraw->number = $number;
        $withdraw->fee = $fee;
        $withdraw->address = $request->input('address');
        $withdraw->note = $request->input('note');
        $withdraw->tag = $request->input('tag');
        if ('USDT' == $coin->name && 'ERC20' == $chainName) {
            $withdraw->is_usdt_erc20 = 1;
        }
        if ('USDT' == $coin->name && 'TRC20' == $chainName) {
            $withdraw->is_usdt_trc20 = 1;
        }

        try {
            DB::transaction(function () use ($user, $number, $withdraw, $coinId) {
                // 保存提现订单
                $withdraw->save();

                /** @var Account $account */
                $account = Account::lockForUpdate()
                    ->where('user_id', $user->id)
                    ->where('coin_id', $coinId)
                    ->first();

                $account->availableDecrement($number);
                $account->disabledIncrement($number);
                $account->proofId = [$withdraw->id, Withdraw::CLASS_ID, Withdraw::OP_APPLY];
                $account->save();
            });
        } catch (Throwable $exception) {
            Log::error($exception);
            $this->error();
        }

        return $this->null();
    }
}
